%{
	#define _CRT_SECURE_NO_WARNINGS
	
    #include <stdio.h>
    #include <stdlib.h>

    const int MAX_SIZE = 4096;
    char buffer[4096];
    char* b_ptr = buffer;

    void get_str();
    char* is_num(char* ptr);
%}
%start E
%token num
%left '+' '-'
%left '*' '/'
%%
E : E'+'T   {printf("stdin: %s            ",b_ptr);printf("reduce by E -> E+T\n");}
    | E'-'T {printf("stdin: %s            ",b_ptr);printf("reduce by E -> E-T\n");}
    | T     {printf("stdin: %s            ",b_ptr);printf("reduce by E -> T\n");}
;
T : T'*'F   {printf("stdin: %s            ",b_ptr);printf("reduce by T -> T*F\n");}
    | T'/'F {printf("stdin: %s            ",b_ptr);printf("reduce by T -> T/T\n");}
    | F     {printf("stdin: %s            ",b_ptr);printf("reduce by T -> F\n");}
;
F : '('E')' {printf("stdin: %s            ",b_ptr);printf("reduce by F -> (E)\n");}
    | num   {printf("stdin: %s            ",b_ptr);printf("reduce by F -> num\n");}
;
%%
int main(){
    get_str();
    return yyparse();
}

int yylex(void){
	static char * end = NULL;
	static int key = 0;
	if(key==1){
		b_ptr++;
		key=0;
	}
	while (*b_ptr != '\0') {
		end = is_num(b_ptr);
		if (end == NULL) {
			key=1;
            printf("stdin: %s            ",b_ptr);
            printf("Shift: Get %c\n",*b_ptr);
            return *b_ptr;
		}
		else {
            printf("stdin: %s            ",b_ptr);
            printf("Shift: Get a number, its value is ");
            for(;b_ptr<end;b_ptr++)
                printf("%c",*b_ptr);
			printf("\n");
            return num;
		}
	}
	return 0;
}

yyerror(char * s){
	printf("%s\n",s);
}

void get_str() {
	int i = 0;
	while (i < MAX_SIZE - 1) {
		char current;
		scanf("%c", &current);
		if (current == '\n') {
			buffer[i] = '\0';
			return;
		}
		else {
			buffer[i] = current;
			i++;
		}
	}
	printf("exceed the maximum!\n");
	exit(1);
}

char* is_num(char* ptr) {
	if ('0' > *ptr || *ptr > '9')
		return NULL;
	while ('0' <= *ptr && *ptr <= '9')
		ptr++;
	if (*ptr == '.') {
		ptr++;
		if ('0' > *ptr || *ptr > '9')
			return NULL;
		while ('0' <= *ptr && *ptr <= '9')
			ptr++;
	}
	if (*ptr == 'E')
		ptr++;
	else return ptr;
	if (*ptr == '+' || *ptr == '-')
		ptr++;
	if ('0' > *ptr || *ptr > '9')
		return NULL;
	while ('0' <= *ptr && *ptr <= '9')
		ptr++;
	return ptr;
}